Feature/optimize editor performance - #7793
Conversation
yanthomasdev
left a comment
There was a problem hiding this comment.
Thanks @sempostma, CI is failing because you need to do npm run format in your branch, I would've done that for you but apparently I can't commit to your branch 😓
yanthomasdev
left a comment
There was a problem hiding this comment.
I found a few things doing another pass here, let me know if they make sense!
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Bumps [axios](https://github.com/axios/axios) from 1.13.5 to 1.15.0. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](axios/axios@v1.13.5...v1.15.0) --- updated-dependencies: - dependency-name: axios dependency-version: 1.15.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [path-to-regexp](https://github.com/pillarjs/path-to-regexp) from 0.1.12 to 0.1.13. - [Release notes](https://github.com/pillarjs/path-to-regexp/releases) - [Changelog](https://github.com/pillarjs/path-to-regexp/blob/v.0.1.13/History.md) - [Commits](pillarjs/path-to-regexp@v0.1.12...v.0.1.13) --- updated-dependencies: - dependency-name: path-to-regexp dependency-version: 0.1.13 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.23 to 4.18.1. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](lodash/lodash@4.17.23...4.18.1) --- updated-dependencies: - dependency-name: lodash-es dependency-version: 4.18.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
* feat: add linked image support for richtext widget * chore: revert config.yml * Apply suggestion from @yanthomasdev Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com> * chore: format * chore: remove useElement * fix: formatting --------- Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
* feat: add break element to widget richtext * fix: format * chore: revert config * chore: revert config
* fix: throw proper errors when i18n entries cannot be retrieved * fix: format i18n code * fix: typescript errors for older versions * fix: typing issue Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com> --------- Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
…ecaporg#7679) * fix(frontmatter): improve duplicate frontmatter key error handling * fix(frontmatter): improve duplicate key warning with file and line info * fix(frontmatter): made duplicate detection path awarness using indendation * fix(frontmatter): removed backslash * feat: use `yaml` diagnostics --------- Co-authored-by: Martin Jagodic <jagodicmartin1@gmail.com> Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
Co-authored-by: Kavanaugh Latiolais <kav@pelo.tech>
…ecaporg#7766) * refactor: add email field to User type Most backends don't need any change because they already populate this field. * feat: add config option to enable Signed-off-by in commit messages Some organizations require Signed-off-by trailers in commit messages (e.g. for Developer Certificate of Origin). GitHub has a setting to enable this when authoring changes from the Web UI. This patch adds a similar setting for DecapCMS. Closes: decaporg#7730 --------- Co-authored-by: Martin Jagodic <jagodicmartin1@gmail.com>
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.3.3 to 3.4.0. - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](cure53/DOMPurify@3.3.3...3.4.0) --- updated-dependencies: - dependency-name: dompurify dependency-version: 3.4.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…org#7364 (decaporg#7440) * fix(markdown): extra whitespace before and after pasted content decaporg#7364 * fix(markdown): better solution for extra whitespace before and after pasted content decaporg#7364 --------- Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
- decap-cms@3.12.0 - decap-cms-app@3.12.0 - decap-cms-backend-git-gateway@3.6.0 - decap-cms-backend-gitea@3.4.0 - decap-cms-backend-github@3.6.0 - decap-cms-core@3.12.0 - decap-cms-editor-component-image@3.3.0 - decap-cms-lib-util@3.5.0 - decap-cms-ui-default@3.6.0 - decap-cms-widget-markdown@3.8.0 - decap-cms-widget-object@3.5.0 - decap-cms-widget-richtext@3.2.0 - decap-server@3.7.0
- decap-cms@3.12.1 - decap-cms-app@3.12.1
…g#6220) * feat: allow special characters to pass through slugification * feat: allow special characters to pass through slugification * chore: combine dev test collections and rename vars * chore: remove any * chore: format * fix typo in test * fix: apply Copilot suggestions * fix: remove unused import * feat: add new preserve slashes tests * fix: add missing type and schema updates * fix: filter empty strings --------- Co-authored-by: Erez Rokah <erezrokah@users.noreply.github.com> Co-authored-by: Martin Jagodic <jagodicmartin1@gmail.com> Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
- decap-cms@3.12.2 - decap-cms-app@3.12.2 - decap-cms-core@3.13.0 - decap-cms-widget-richtext@3.2.1
…aporg#7443) * fix: dynamic codemirror mode imports * style: format code * fix: await function and add error handling --------- Co-authored-by: Martin Jagodic <jagodicmartin1@gmail.com> Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
* fix: adhere to remark's tokenizer rules decaporg#7315 * fix: merge and improve tests --------- Co-authored-by: Martin Jagodic <jagodicmartin1@gmail.com> Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
…data (decaporg#7667) The `invokeEvent` function in registry.js was returning only the data payload (`_data.entry.get('data')`) instead of returning the complete entry object. This caused entry metadata fields (slug, path, meta, etc.) to be lost during event processing, particularly affecting file collections that rely on slug for file lookups. When `invokePreSaveEvent` was called during entry persistence: 1. Entry starts with all metadata: slug, path, meta, isModification, etc. 2. `invokeEvent` is called with the full entry object 3. `invokeEvent` returns ONLY the data payload, stripping metadata 4. Calling code replaces the full entry with just the data payload 5. Downstream operations like `entryToRaw` receive incomplete entry 6. `fieldsOrder` method fails trying to match slug to file definitions This manifested as errors like: - "No file found for undefined in [collection]" - "TypeError: can't access property 'toJS', file is undefined" The bug was introduced in commit 0d7e36b (January 31, 2020) and has existed for ~5 years, but was only exposed in recent versions (3.2.0+) when file collection persistence logic started calling `invokePreSaveEvent` and fully relying on its return value to update the entry draft. Changed `invokeEvent` to return `_data.entry` (the complete entry object) instead of `_data.entry.get('data')` (just the data payload). This preserves all entry metadata through the event handler chain, ensuring that callers like `invokePreSaveEvent` receive the complete entry object with all properties intact. Verified fix resolves file collection publishing issues where: - Custom widgets modify entry data during save - File collections with single files rely on slug matching - Entry metadata must be preserved through preSave event handlers Fixes #[issue-number-if-exists] fix(core): test returning full entry when invoking preSave handler Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com> Co-authored-by: Martin Jagodic <jagodicmartin1@gmail.com>
…e/EditorControl.js Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
…e/EditorControl.js Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
7ffee68 to
5a4c351
Compare
Nice, I made some changes and rebased the branch. |
yanthomasdev
left a comment
There was a problem hiding this comment.
Thanks @sempostma, one small comment and I believe it should be good to go. I just need you to update branch here since the branch is protected and I can't do it myself
Co-authored-by: Yan <61414485+yanthomasdev@users.noreply.github.com>
✅ Deploy Preview for decap-cms ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
yanthomasdev
left a comment
There was a problem hiding this comment.
Hey @sempostma, the branch seems to be in a dirty state right now, could you take a look and fix the merge conflicts? Thanks!
Resolves conflicts with two upstream changes: - Widget.js: upstream switched to the named `createElement` import; kept that while keeping the added `getEntry` prop alongside the deprecated `entry`. - ListControl.js: upstream decaporg#7972 made `handleChangeFor` route changes by the item's id instead of its position. This branch had memoized it on the index for a stable `onChangeObject` reference. Memoize on the item key instead, which keeps the reference stable and preserves the id based routing — memoizing on the index would have reintroduced decaporg#7972, since a handler cached at a position would keep firing against whatever item later occupies it. The two regression tests from decaporg#7972 now look up the key for the position they target.
yanthomasdev
left a comment
There was a problem hiding this comment.
LGTM! Could you just rebase so we exclude all these commits that aren't really part of the changes done here?
Note
I had to close and ropen #7719 because I moved my decap-cms fork repository to an organization.
This PR simply prevents a rerender of the entire EditorControl tree. This is done by making all the props stable, aka not passing new references when its not needed.
The risk with this change is that it's very easy for someone to create a new commit that reintroduces in an unstable prop which would cause the same performance issues again.
Summary
I'm using Decap for a project with a very large collection schema with reorder-able blocks and lists. On a 2024's machine, typing is almost impossible so not acceptable as a deliverable.
Test plan
The best way to test it is adding a 'shouldComponentUpdate' to the editorControl:
If you add this to the current main branch, you will see hundreds of messages. After the change this drops to 3 or 4 (for each keystroke you type in a field for example).
Checklist
A picture of a cute animal (not mandatory but encouraged)